package com.miage.kangourou.server.business;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpSession;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.miage.kangourou.client.GetListesService;
import com.miage.kangourou.client.beans.Enseignant;
import com.miage.kangourou.client.beans.Evenement;
import com.miage.kangourou.client.beans.Groupe;
import com.miage.kangourou.client.beans.Matiere;
import com.miage.kangourou.client.beans.Promo;
import com.miage.kangourou.client.beans.Salle;
import com.miage.kangourou.client.beans.TypeEvenement;
import com.miage.kangourou.client.beans.Ue;
import com.miage.kangourou.client.beans.Utilisateur;
import com.miage.kangourou.server.dao.impl.DAOFactory;
import com.miage.kangourou.server.dao.impl.EvenementDao;
import com.miage.kangourou.server.dao.impl.GenericDao;
import com.miage.kangourou.server.dao.impl.GroupeDao;
import com.miage.kangourou.server.dao.impl.MatiereDao;
import com.miage.kangourou.server.dao.impl.UtilisateurDao;

public class GetListesServiceImpl extends RemoteServiceServlet implements
		GetListesService, Serializable {
	private static final long serialVersionUID = 1L;

	private GenericDao<Salle> salleDao;
	private GenericDao<TypeEvenement> typeDao;
	private GenericDao<Enseignant> enseignantDao;
	private GenericDao<Ue> ueDao;
	private GenericDao<Promo> promoDao;
	private GenericDao<Groupe> groupeDao;
	private GenericDao<Matiere> matiereDao;
	private GenericDao<Evenement> evenementDao;

	public int createEvent(Evenement evenement) {
		try {
			evenementDao.create(evenement);

			return 1;

		} catch (SQLException e) {
			e.printStackTrace();

			return 0;
		}

	}

	@SuppressWarnings("deprecation")
	public int createEventRecurrence(Evenement evenement, Date startPeriode,
			Date endPeriode, List<Integer> joursCoches) {

		int nbEnregistrements = 0;

		int id_evenement_recurrence;
		try {
			id_evenement_recurrence = ((EvenementDao) evenementDao)
					.findRecurrenceId();
			evenement.setId_evenement_recurrence(id_evenement_recurrence);

			endPeriode.setHours(23);
			endPeriode.setMinutes(59);

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(startPeriode);

			Date startDate = new Date();
			Date endDate = new Date();

			startDate.setTime(evenement.getStart().getTime());
			endDate.setTime(evenement.getEnd().getTime());

			while (endPeriode.after(calendar.getTime())) {
				if (joursCoches
						.contains(calendar.get(Calendar.DAY_OF_WEEK) - 1)) {
					evenement.setStart(calendar.getTime());
					evenement.getStart().setHours(startDate.getHours());
					evenement.getStart().setMinutes(startDate.getMinutes());

					evenement.setEnd(calendar.getTime());
					evenement.getEnd().setHours(endDate.getHours());
					evenement.getEnd().setMinutes(endDate.getMinutes());

					evenementDao.create(evenement);

					nbEnregistrements++;
				}

				calendar.add(Calendar.DATE, 1);
			}
		} catch (SQLException e1) {
			e1.printStackTrace();
		}

		return nbEnregistrements;
	}

	@Override
	public boolean deleteEvents(List<Integer> idsEventsToDelete) {

		boolean isDeleteSuccess = false;

		if (!idsEventsToDelete.equals(null) && !idsEventsToDelete.isEmpty()) {
			for (Integer id : idsEventsToDelete) {
				isDeleteSuccess = evenementDao.delete(id);
				if (!isDeleteSuccess) {
					break;
				}
			}
		}

		return isDeleteSuccess;
	}

	@Override
	public Evenement findById(int id) {
		Evenement evt = new Evenement();

		try {
			evt = ((EvenementDao) evenementDao).findById(id);
			evt.setId_promo(((GroupeDao) groupeDao)
					.findById(evt.getId_groupe()).getId_promo());
			evt.setId_ue(((MatiereDao) matiereDao)
					.findById(evt.getId_matiere()).getId_ue());
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return evt;
	}

	public List<Date> findCreneauxLibres(ArrayList<Integer> groupes,
			Date dateDebut, int heureDebut, int minDebut, int heureFin,
			int minFin) {

		ArrayList<Date> creneaux = ((EvenementDao) evenementDao)
				.findCreneauxLibres(groupes, dateDebut, heureDebut, minDebut,
						heureFin, minFin);

		return creneaux;
	}

	public List<Enseignant> getEnseignantList() {
		enseignantDao = DAOFactory.getEnseignantDao();

		List<Enseignant> enseignants = new ArrayList<Enseignant>();

		try {
			enseignants = enseignantDao.findAll();
		} catch (Exception e) {
			System.out.println("getEnseignantList");
			e.printStackTrace();
		}

		return enseignants;
	}

	@Override
	public List<Evenement> getEvenementBetweenTwoDateAndCriteria(int idGroupe,
			int idEnseignant, int idSalle, int idMatiere, Date debut, Date fin) {

		evenementDao = DAOFactory.getEvenementDao();

		List<Evenement> evenements = new ArrayList<Evenement>();

		try {
			evenements = ((EvenementDao) evenementDao)
					.findEventBetween2DateAndWithCriteria(idGroupe,
							idEnseignant, idSalle, idMatiere, debut, fin);

			for (Evenement e : evenements) {

				e.configureAppointment(DAOFactory.getEnseignantDao().findById(
						e.getId_enseignant()).getNom(), DAOFactory
						.getMatiereDao().findById(e.getId_matiere())
						.getIntitule(), DAOFactory.getGroupeDao().findById(
						e.getId_groupe()).getIntitule(), DAOFactory
						.getSalleDao().findById(e.getId_salle()).getIntitule(),
						DAOFactory.getGroupeDao().findById(e.getId_groupe())
								.getColor());
			}
		} catch (Exception e) {
			System.out.println("getEvenementBetweenTwoDate");
			e.printStackTrace();
		}

		return evenements;
	}

	public List<Evenement> getEvenementList() {
		evenementDao = DAOFactory.getEvenementDao();

		List<Evenement> evenements = new ArrayList<Evenement>();

		try {
			evenements = evenementDao.findAll();
		} catch (Exception e) {
			System.out.println("getEvenementList");
			e.printStackTrace();
		}

		return evenements;
	}

	public List<Groupe> getGroupeList() {
		groupeDao = DAOFactory.getGroupeDao();

		List<Groupe> groupes = new ArrayList<Groupe>();

		try {
			groupes = groupeDao.findAll();
		} catch (Exception e) {
			System.out.println("getGroupeList");
			e.printStackTrace();
		}

		return groupes;
	}

	public List<Groupe> getGroupeListFromUe(int promo) {
		groupeDao = DAOFactory.getGroupeDao();

		List<Groupe> groupes = new ArrayList<Groupe>();

		try {
			groupes = ((GroupeDao) groupeDao).findByIdPromo(promo);
		} catch (Exception e) {
			System.out.println("getGroupeListFromPromo");
			e.printStackTrace();
		}

		return groupes;
	}

	public List<Matiere> getMatiereList() {
		matiereDao = DAOFactory.getMatiereDao();

		List<Matiere> matieres = new ArrayList<Matiere>();

		try {
			matieres = matiereDao.findAll();
		} catch (Exception e) {
			System.out.println("getMatiereList");
			e.printStackTrace();
		}

		return matieres;
	}

	public List<Matiere> getMatiereListFromUe(int ue) {
		matiereDao = DAOFactory.getMatiereDao();

		List<Matiere> matieres = new ArrayList<Matiere>();

		try {
			matieres = ((MatiereDao) matiereDao).findByIdUe(ue);
		} catch (Exception e) {
			System.out.println("getMatiereListFromUe");
			e.printStackTrace();
		}

		return matieres;
	}

	public List<Promo> getPromoList() {
		promoDao = DAOFactory.getPromoDao();

		List<Promo> promos = new ArrayList<Promo>();

		try {

			promos = promoDao.findAll();
		} catch (Exception e) {
			System.out.println("getPromoList");
			e.printStackTrace();
		}

		return promos;
	}

	public List<Salle> getSalleList() {
		salleDao = DAOFactory.getSalleDao();

		List<Salle> salles = new ArrayList<Salle>();

		try {

			salles = salleDao.findAll();
		} catch (Exception e) {
			System.out.println("getSalleList");
			e.printStackTrace();
		}

		return salles;
	}

	private HttpSession getSession() {
		// Get the current request and then return its session
		return this.getThreadLocalRequest().getSession();
	}

	public List<TypeEvenement> getTypeList() {
		typeDao = DAOFactory.getTypeEvenementDao();

		List<TypeEvenement> types = new ArrayList<TypeEvenement>();

		try {
			types = typeDao.findAll();
		} catch (Exception e) {
			System.out.println("getTypeList");
			e.printStackTrace();
		}

		return types;
	}

	public List<Ue> getUEList() {
		ueDao = DAOFactory.getUeDao();

		List<Ue> ues = new ArrayList<Ue>();

		try {
			ues = ueDao.findAll();
		} catch (Exception e) {
			System.out.println("getUEList");
			e.printStackTrace();
		}

		return ues;
	}

	@Override
	public Utilisateur login(String email, String password) {

		Utilisateur utilisateurRecup = new Utilisateur();

		try {
			UtilisateurDao utilDao = (UtilisateurDao) DAOFactory
					.getUtilisateurDao();
			utilisateurRecup = utilDao.findByLogin(email, password);

		} catch (SQLException e) {

			e.printStackTrace();
		}

		// On test ici si l'utilisateur est le bon
		// if is empty , is loged a faux , if isAdmin , isloged

		return utilisateurRecup;

	}

	public Utilisateur loginUsingCookie(String cookie) {

		Utilisateur utilisateurRecup = new Utilisateur();

		try {
			UtilisateurDao utilDao = (UtilisateurDao) DAOFactory
					.getUtilisateurDao();
			utilisateurRecup = utilDao.findByCookie(cookie);

		} catch (SQLException e) {

			e.printStackTrace();
		}

		return utilisateurRecup;
	}

	public int updateEvent(Evenement evenement) {
		try {
			((EvenementDao) evenementDao).update(evenement);

			return 1;

		} catch (SQLException e) {
			e.printStackTrace();

			return 0;
		}
	}

	public boolean updateEventDate(int id_event, Date debut, Date fin,
			Utilisateur util) {

		if (util.isAdmin()) {
			return ((EvenementDao) evenementDao).updateEventDate(id_event,
					debut, fin);
		} else {
			return false;
		}
	}

}
